package com.eliasbalasis.dwr4gwt.example;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Random;
import javax.servlet.ServletContext;

import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.ScriptProxy;
import org.directwebremoting.util.Logger;

/**
 * A generator of random objects to push to GI
 * @author Joe Walker [joe at getahead dot ltd dot uk]
 */
public class Publisher implements Runnable
{
    /**
     * Create a new publish thread and start it
     */
    public Publisher()
    {
        WebContext webContext = WebContextFactory.get();
        ServletContext servletContext = webContext.getServletContext();

        serverContext = ServerContextFactory.get(servletContext);

        // A bit nasty: the call to serverContext.getScriptSessionsByPage()
        // below could fail because the system might need to read web.xml which
        // means it needs a ServletContext, which is only available  using
        // WebContext, which in turn requires a DWR thread. We can cache the
        // results simply by calling this in a DWR thread, as we are now.
        webContext.getScriptSessionsByPage("");

        synchronized (Publisher.class)
        {
            if (worker == null)
            {
                worker = new Thread(this, "Publisher");
                worker.start();
            }
        }
    }

    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
        try
        {
            log.info("Starting Publisher thread");

            while (!Thread.currentThread().isInterrupted())
            {
                //Collection sessions = serverContext.getScriptSessionsByPage("/dwr4gwt/withoutIFrame.html");
            	//Collection sessions = serverContext.getAllScriptSessions();
                Collection sessions = serverContext.getScriptSessionsByPage("/dwr4gwt/gwt/com.eliasbalasis.dwr4gwt.test.Test/Test.html");
                if (sessions.size()>0) {
	                ScriptProxy proxy = new ScriptProxy(sessions);

	                Iterator sessionsIterator = sessions.iterator();
	                while(sessionsIterator.hasNext()) {
	                	ScriptSession session = (ScriptSession)sessionsIterator.next();
	                	Iterator attributesIterator = session.getAttributeNames();
	                	while (attributesIterator.hasNext()) {
	                		String attributeName = (String)attributesIterator.next();
	                		attributeName.length();
	                	}
	                }

	        		PersonRepository personRepository = new PersonRepository();
	        		personRepository.setName("testRepository");
	        		Collection persons = new ArrayList();
	        		//
	        		Person person1 = new Person();
	        		person1.setName("person1");
	        		person1.setDescription("This is person1");
	        		person1.setIntValue(101);
	        		person1.setDateValue(new Date());
	        		person1.setFloatValue(0.101f);
	        		person1.setDoubleValue(Double.POSITIVE_INFINITY);
	        		person1.setBooleanValue(true);
	        		//
	        		Person person2 = new Person();
	        		person2.setName("person2");
	        		person2.setDescription("This is person2");
	        		person2.setIntValue(102);
	        		person2.setDateValue(new Date());
	        		person2.setFloatValue(0.102f);
	        		person2.setDoubleValue(Double.NaN);
	        		person2.setBooleanValue(false);
	        		//
	        		Person person3 = new Person();
	        		person3.setName("person3");
	        		person3.setDescription("This is person3");
	        		person3.setIntValue(103);
	        		person3.setDateValue(new Date());
	        		person3.setFloatValue(0.103f);
	        		person3.setDoubleValue(1.7976e308d);
	        		person3.setBooleanValue(false);
	        		persons.add(person1);
	        		persons.add(person2);
	        		persons.add(person3);
	        		personRepository.setPersons(persons);
	                proxy.addFunctionCall("window.PageBus.publish", "com.eliasbalasis.dwr4gwt.publisher.subject", personRepository, null);
                }

                int timeToSleep = random.nextInt(15000);
                Thread.sleep(timeToSleep);
            }
        }
        catch (InterruptedException ex)
        {
            // Ignore, we expect this
        }
        finally
        {
            log.info("Stopping Publisher thread");
        }
    }

    /**
     * The thread that does the work
     */
    protected static Thread worker;

    /**
     * We use DWRs ServerContext to find users of a given page
     */
    private ServerContext serverContext;

    /**
     * Used to generate random data
     */
    private Random random = new Random();

    /**
     * The log stream
     */
    private static final Logger log = Logger.getLogger(Publisher.class);
}
